package controllers

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"weiboxs.com/new_h_glasses/enums"
	"weiboxs.com/new_h_glasses/models"
	"weiboxs.com/new_h_glasses/utils"

	beego "github.com/beego/beego/v2/adapter"
)

type BaseController struct {
	beego.Controller
	controllerName string             //当前控制名称
	actionName     string             //当前action名称
	curUser        models.BackendUser //当前用户信息
	layoutSections map[string]string
}

func (c *BaseController) Prepare() {
	//附值
	c.controllerName, c.actionName = c.GetControllerAndAction()

	c.adapterUserInfo()

	//设置页面Page
	c.Data["pageTitle"] = beego.AppConfig.String("site::page_title")
	//生成xsrf
	c.Data["xsrf_token"] = c.XSRFToken()
}

// checkLogin判断用户是否登录，未登录则跳转至登录页面
// 一定要在BaseController.Prepare()后执行
func (c *BaseController) checkLogin() {
	if c.curUser.Id == 0 || c.curUser.DepartmentId == 0 {
		//登录页面地址
		urlstr := c.URLFor("LoginController.Login") + "?url="
		//登录成功后返回的址为当前
		returnURL := c.Ctx.Request.URL.Path
		//如果ajax请求则返回相应的错码和跳转的地址
		if c.Ctx.Input.IsAjax() {
			//由于是ajax请求，因此地址是header里的Referer
			returnURL := c.Ctx.Input.Refer()
			c.jsonResult(enums.JRCode302, "请登录", urlstr+returnURL)
		}
		c.Redirect(urlstr+returnURL, 302)
		c.StopRun()
	}
}

// 判断某 Controller.Action 当前用户是否有权访问
func (c *BaseController) checkActionAuthor(authName string) bool {
	if c.curUser.Id == 0 {
		return false
	}

	v := c.curUser

	//如果是超级管理员，则直接通过
	if v.IsSuper == true {
		return true
	}
	resourceList := models.ResourceTreeGridByUserId(c.curUser.Id, 1000)
	//遍历用户所负责的资源列表
	for i, _ := range resourceList {
		urlfor := strings.TrimSpace(resourceList[i].UrlFor)
		if len(urlfor) == 0 {
			continue
		}

		// TestController.Get,:last,xie,:first,asta
		strs := strings.Split(urlfor, ",")
		if len(strs) > 0 && strs[0] == authName {
			return true
		}
	}

	return false
}

// checkLogin判断用户是否有权访问某地址，无权则会跳转到错误页面
// 一定要在BaseController.Prepare()后执行
// 会调用checkLogin
// 传入的参数为忽略权限控制的Action
func (c *BaseController) checkAuthor(authName string) {
	//先判断是否登录
	c.checkLogin()
	hasAuthor := c.checkActionAuthor(authName)
	if hasAuthor == false {
		utils.LogDebug(fmt.Sprintf("author control: path=%s.%s userid=%v  无权访问", c.controllerName, c.actionName, c.curUser.Id))
		//如果没有权限
		if c.Ctx.Input.IsAjax() {
			c.jsonResult(enums.JRCode401, "无权访问", "")
		} else {
			c.pageError("无权访问")
		}
	}
}

// 从session里取用户信息
func (c *BaseController) adapterUserInfo() {

	userString := c.Ctx.GetCookie("h_userLogin")
	userinfo := models.BackendUser{}
	encrypt, _ := utils.Decrypt(userString)
	if err := json.Unmarshal([]byte(encrypt), &userinfo); err != nil {
		return
	}
	userinfo.ExtendDepartmentList = strings.Split(strings.Trim(userinfo.ExtendDepartment, " "), ",")
	userinfo.ExtendDepartmentList = append(userinfo.ExtendDepartmentList, strconv.FormatInt(userinfo.DepartmentId, 10))
	c.curUser = userinfo
	c.Data["backenduser"] = c.curUser

	//获取部门信息
	s, _ := models.DepartmentCacheById(c.curUser.DepartmentId)
	c.Data["department"] = s
	//models.CurLoginUserDepId = s.Id
}

// SetBackendUser2Session 获取用户信息（包括资源UrlFor）保存至Session
func (c *BaseController) setBackendUser2Session(userId int) error {
	m, err := models.BackendUserOne(userId)
	if err != nil {
		return err
	}
	var isSuper int = 0
	if m.IsSuper {
		isSuper = 1
	}
	c.SetSession("h_userLogin", fmt.Sprintf("%d", m.Id)+"||"+m.UserName+"||"+m.Avatar+"||"+m.Mobile+"||"+m.RealName+"||"+fmt.Sprintf("%d", isSuper)+"||"+fmt.Sprintf("%d", m.DepartmentId))

	//获取这个用户能获取到的所有资源列表
	resourceList := models.ResourceTreeGridByUserId(userId, 1000)

	var urlListString = ""
	for _, item := range resourceList {
		urlListString += strings.TrimSpace(item.UrlFor) + ","
	}

	c.SetSession("h_userLogin_Resource", strings.Trim(urlListString, ","))

	return nil
}

// 设置模板，第一个参数模板，第二个参数为扩展JS，第三个为layout
func (c *BaseController) display(template ...string) {
	var tplName string
	layout := "shared/layout_page.html"
	c.LayoutSections = make(map[string]string)

	switch {

	case len(template) == 1:

		tplName = template[0]

	case len(template) == 2:

		tplName = template[0]
		if template[1] != "" {
			c.LayoutSections["footerjs"] = template[1]
		}

	case len(template) == 3:
		tplName = template[0]

		if template[1] != "" {
			c.LayoutSections["footerjs"] = template[1]
		}

		layout = template[2]
	}

	if tplName == "" {
		//不要Controller这个10个字母
		ctrlName := strings.ToLower(c.controllerName[0 : len(c.controllerName)-10])
		actionName := strings.ToLower(c.actionName)
		tplName = ctrlName + "/" + actionName + ".html"
	}

	c.Layout = layout
	c.TplName = tplName
}

func (c *BaseController) jsonResult(code enums.JsonResultCode, msg string, data interface{}) {
	r := &models.JsonResult{code, msg, data}
	c.Data["json"] = r
	c.ServeJSON()
	c.StopRun()
}

// 返回datatables格式数据
func (c *BaseController) jsonDataTable(total int64, rows interface{}) {
	r := make(map[string]interface{})

	r["iTotalRecords"] = 0
	r["iTotalDisplayRecords"] = total
	r["aaData"] = rows

	c.Data["json"] = r
	c.ServeJSON()
	c.StopRun()
}

// 重定向
func (c *BaseController) redirect(url string) {
	c.Redirect(url, 302)
	c.StopRun()
}

// 重定向 去错误页
func (c *BaseController) pageError(msg string) {
	if c.Ctx.Input.IsAjax() {
		c.jsonResult(enums.JRCodeFailed, msg, "")
	} else {
		errorurl := c.URLFor("HomeController.Error") + "/" + msg
		c.Redirect(errorurl, 302)
		c.StopRun()
	}
}

// 重定向 去登录页
func (c *BaseController) pageLogin() {
	url := c.URLFor("LoginController.Login")
	c.Redirect(url, 302)
	c.StopRun()
}

// 输出公共产品类别
func (c *BaseController) showErpTypeid() map[int]string {
	typeid := models.GetErpTypeid()
	c.Data["erptypeid"] = typeid
	return typeid
}

// 输出
func (c *BaseController) erpPublicConfig() (map[int]string, map[int]string, map[int]string) {
	paymode := models.PayMode
	paymethod := models.PayMethod
	deliverymode := models.DeliveryMode
	return paymode, paymethod, deliverymode
}

// 验证可控部门
func (c *BaseController) checkDepControl(depid int64) bool {
	for _, v := range c.curUser.ExtendDepartmentList {
		n := fmt.Sprintf("%d", depid)
		if v == n {
			return true
		}
	}
	return false
}
